#!/usr/bin/env python

VERSION = "0.0.1"

import sys, os
try:
	import pygtk
	pygtk.require("2.0")
except:
	print "Could not import pygtk"

try:
	import gtk
	import gtk.glade
except:
	print "Could not import gtk"
	sys.exit(1)

class Func:
	"""
	A pseudo-widget representing an a10 function.
	"""
	
	def __init__(self, x, y):
		self.x = x - 32
		self.y = y - 16
		self.w = 64
		self.h = 32
		self.selected = 0
		
	def draw (self, gc, canvas):
		cmap = canvas.get_colormap()
		
		# Draw background.
		if self.selected == 1:
			gc.foreground = cmap.alloc("#FF9")
		elif self.selected == 2:
			gc.foreground = cmap.alloc("#F99")
		else:
			gc.foreground = cmap.alloc("#EEE")
		canvas.draw_arc(gc, True, int(self.x), int(self.y), int(self.w), int(self.h), 0, 360*64)
		# Draw outline.
		gc.foreground = cmap.alloc("#000")
		canvas.draw_arc(gc, False, int(self.x), int(self.y), int(self.w), int(self.h), 0, 360*64)
		
	def invalidate (self, canvas):
		"""
		Invalidate the widgets bounding rectangle so that an expose event is generated.
		"""
		canvas.window.invalidate_rect((int(self.x), int(self.y), int(self.w+1), int(self.h+1)), True)
		
	def select (self, flag, canvas):
		self.selected = flag
		self.invalidate(canvas)

SELECTION_CONNECT = 1
SELECTION_SELECTED = 2

class A10:
	"""
	The main interface class
	"""
	
	def __init__(self):
		"""
		Initialise the main window
		"""
		
		self.version = VERSION

		self.title = "a10"
		self.xml = gtk.glade.XML("a10gui.glade")
		self.window = self.xml.get_widget("mainWindow")
		self.canvas = gtk.DrawingArea()
		self.canvas.set_size_request(400, 300)
		self.box  = self.xml.get_widget("eventbox1")
		self.box.add(self.canvas)
				
		self.connectEvents()
		
		self.funcs = []
		self.dragging = None
		self.connection = None
		self.selection = None
		
		# Show widgets.
		self.canvas.show()
		self.window.show()
		
	def connectEvents(self):
		"""
		Connect events to the various widgets
		"""
		
		self.box.set_events(gtk.gdk.BUTTON_PRESS)
		self.box.set_events(gtk.gdk.BUTTON_RELEASE)
		self.box.set_events(gtk.gdk.MOTION_NOTIFY)
		
		self.window.connect("delete_event", self.on_Close)
		self.canvas.connect("expose-event", self.on_DrawCanvas)
		self.box.connect("button-press-event", self.on_Click)
		self.box.connect("button-release-event", self.on_Release)
		self.box.connect("motion-notify-event", self.on_Drag)

	def on_Close(self, widget=None, event=None):
		gtk.main_quit()
		
	def on_DrawCanvas(self, widget=None, event=None):
		style = self.canvas.get_style()
		gc = style.fg_gc[gtk.STATE_NORMAL]
		#dirty = self.canvas.window.get_update_area()
		for item in self.funcs:
			#if dirty.rect_in((item.x, item.y, item.w, item.h)):
			item.draw(gc, self.canvas.window)
		return True
	
	def on_Click (self, widget=None, event=None):
		if event.button == 1:
			if self.connection != None:
				self.connection.select(0, self.canvas)
				self.connection = None
			if self.selection != None:
				self.selection.select(0, self.canvas)
				
			index = 0
			for item in self.funcs:
				if event.x >= item.x and event.x < item.x + item.w and event.y >= item.y and event.y < item.y + item.h:
					self.dragging = (index, event.x - item.x, event.y - item.y)
					self.selection = item
					self.selection.select(SELECTION_SELECTED, self.canvas)
					return True
				else:
					index += 1
			
			func = Func(event.x, event.y)
			self.funcs.append(func)
			self.selection = func
			self.selection.select(SELECTION_SELECTED, self.canvas)
		
		elif event.button == 3:
			index = 0
			for item in self.funcs:
				if event.x >= item.x and event.x < item.x + item.w and event.y >= item.y and event.y < item.y + item.h:
					if self.connection:
						self.connection.select(0, self.canvas)
						self.connection = None
					else:
						self.connection = item
						self.connection.select(SELECTION_CONNECT, self.canvas)
					return True
				else:
					index += 1
			if self.connection != None:
				self.connection.select(0, self.canvas)
				self.connection = None

	def on_Drag (self, widget=None, event=None):
		if self.dragging != None:
			self.funcs[self.dragging[0]].invalidate(self.canvas)
			self.funcs[self.dragging[0]].x = event.x - self.dragging[1]
			self.funcs[self.dragging[0]].y = event.y - self.dragging[2]
			self.funcs[self.dragging[0]].invalidate(self.canvas)

	def on_Release (self, widget=None, event=None):
		self.dragging = None

if __name__ == "__main__":
	a10 = A10()
	gtk.main()
